import tkinter as tk
from tkinter import ttk, messagebox, filedialog, colorchooser
import webbrowser

class TkinterTutorial:
	def __init__(self, root):
    		self.root = root
            		self.root.title("Python Tkinter 详细教学")
                    		self.root.geometry("800x700")
                            		self.root.configure(bg="#f0f0f0")
                                    		
                                            		# 创建标签框架
                                                    		self.notebook = ttk.Notebook(root)
                                                            		self.notebook.pack(fill='both', expand=True, padx=10, pady=10)
                                                                    		
                                                                            		# 创建各个标签页
                                                                                    		self.create_welcome_tab()
                                                                                            		self.create_basic_widgets_tab()
                                                                                                    		self.create_layout_tab()
                                                                                                            		self.create_advanced_widgets_tab()
                                                                                                                    		self.create_dialogs_tab()
                                                                                                                            		self.create_menu_tab()
                                                                                                                                    		self.create_theme_tab()
                                                                                                                                            		
                                                                                                                                                    	def create_welcome_tab(self):
                                                                                                                                                        		# 欢迎标签页
                                                                                                                                                                		tab = ttk.Frame(self.notebook)
                                                                                                                                                                        		self.notebook.add(tab, text="欢迎")
                                                                                                                                                                                		
                                                                                                                                                                                        		title = tk.Label(tab, text="Python Tkinter 详细教学", 
                                                                                                                                                                                                						font=("Arial", 24, "bold"), fg="#2c3e50")
                                                                                                                                                                                                                        		title.pack(pady=20)
                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                        		intro = tk.Label(tab, text="Tkinter 是 Python 的标准 GUI 库，用于创建桌面应用程序。\n"
                                                                                                                                                                                                                                                								  "它简单易学，功能强大，适合快速开发各种图形界面程序。",
                                                                                                                                                                                                                                                                                  						font=("Arial", 12), justify="left", wraplength=600)
                                                                                                                                                                                                                                                                                                          		intro.pack(pady=10)
                                                                                                                                                                                                                                                                                                                  		
                                                                                                                                                                                                                                                                                                                          		features = tk.Label(tab, text="本教程涵盖以下内容：\n"
                                                                                                                                                                                                                                                                                                                                  									 "✓ 基础组件（标签、按钮、输入框等）\n"
                                                                                                                                                                                                                                                                                                                                                                       									 "✓ 布局管理（pack、grid、place）\n"
                                                                                                                                                                                                                                                                                                                                                                                                            									 "✓ 高级组件（列表框、树形视图、进度条等）\n"
                                                                                                                                                                                                                                                                                                                                                                                                                                                 									 "✓ 对话框（消息框、文件选择、颜色选择等）\n"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      									 "✓ 菜单和工具栏\n"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           									 "✓ 主题和样式定制",
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                						font=("Arial", 12), justify="left")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		features.pack(pady=20)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		github = tk.Label(tab, text="查看完整代码: https://github.com/example/tkinter-tutorial", 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                						 fg="blue", cursor="hand2", font=("Arial", 10))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         		github.pack(pady=10)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 		github.bind("<Button-1>", lambda e: webbrowser.open("https://github.com"))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 	def create_basic_widgets_tab(self):
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		# 基础组件标签页
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		tab = ttk.Frame(self.notebook)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		self.notebook.add(tab, text="基础组件")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		# 标签
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		label_frame = ttk.LabelFrame(tab, text="标签 (Label)")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		label_frame.pack(fill='x', padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		label1 = tk.Label(label_frame, text="普通标签", font=("Arial", 12))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		label1.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             		label2 = tk.Label(label_frame, text="带背景色的标签", font=("Arial", 12), 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     						 bg="#3498db", fg="white", padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		label2.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		# 按钮
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      		button_frame = ttk.LabelFrame(tab, text="按钮 (Button)")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		button_frame.pack(fill='x', padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		def button_click():
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      			messagebox.showinfo("按钮事件", "你点击了按钮！")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  			
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		button1 = tk.Button(button_frame, text="普通按钮", command=button_click, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      						  bg="#2ecc71", fg="white", font=("Arial", 12))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		button1.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		button2 = tk.Button(button_frame, text="禁用按钮", state='disabled')
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		button2.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		# 输入框
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		entry_frame = ttk.LabelFrame(tab, text="输入框 (Entry)")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		entry_frame.pack(fill='x', padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		entry_label = tk.Label(entry_frame, text="输入内容:")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		entry_label.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		self.entry_var = tk.StringVar()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		entry = tk.Entry(entry_frame, textvariable=self.entry_var, width=30)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		entry.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		def show_entry():
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        			messagebox.showinfo("输入内容", f"你输入了: {self.entry_var.get()}")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    			
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		entry_button = tk.Button(entry_frame, text="显示输入", command=show_entry)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		entry_button.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		# 复选框
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		check_frame = ttk.LabelFrame(tab, text="复选框 (Checkbutton)")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		check_frame.pack(fill='x', padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		self.check_var1 = tk.BooleanVar()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		self.check_var2 = tk.BooleanVar()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		check1 = tk.Checkbutton(check_frame, text="选项一", variable=self.check_var1)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		check1.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		check2 = tk.Checkbutton(check_frame, text="选项二", variable=self.check_var2)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		check2.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		def show_checks():
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        			result = f"选项一: {'是' if self.check_var1.get() else '否'}\n"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    			result += f"选项二: {'是' if self.check_var2.get() else '否'}"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                			messagebox.showinfo("复选框状态", result)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            			
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		check_button = tk.Button(check_frame, text="显示状态", command=show_checks)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		check_button.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		# 单选按钮
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		radio_frame = ttk.LabelFrame(tab, text="单选按钮 (Radiobutton)")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		radio_frame.pack(fill='x', padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		self.radio_var = tk.StringVar(value="选项一")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		radio1 = tk.Radiobutton(radio_frame, text="选项一", variable=self.radio_var, value="选项一")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		radio1.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		radio2 = tk.Radiobutton(radio_frame, text="选项二", variable=self.radio_var, value="选项二")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		radio2.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		radio3 = tk.Radiobutton(radio_frame, text="选项三", variable=self.radio_var, value="选项三")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		radio3.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		def show_radio():
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                			messagebox.showinfo("单选按钮", f"你选择了: {self.radio_var.get()}")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            			
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		radio_button = tk.Button(radio_frame, text="显示选择", command=show_radio)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                		radio_button.pack(side='left', padx=5, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                	def create_layout_tab(self):
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    		# 布局管理标签页
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            		tab = ttk.Frame(self.notebook)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    		self.notebook.add(tab, text="布局管理")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    		# Pack 布局
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            		pack_frame = ttk.LabelFrame(tab, text="Pack 布局")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    		pack_frame.pack(fill='both', expand=True, padx=10, pady=5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            		
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    		pack_desc = tk.Label(pack_frame, text="Pack 布局按照添加顺序")